/**
 * 节点树中的一个节点
 * 每个节点都有指针指向父节点，子节点，以及左右的兄弟节点
 */

export class MNode {
  public parent: MNode | null = null;
  public firstChild: MNode | null = null;
  public lastChild: MNode | null = null;
  public prev: MNode | null = null;
  public next: MNode | null = null;

  public type: string = '';  // 节点类型
  public isContainer: boolean = false; // 是否可以有子节点
  public text: string = '';

  // 从树种删除该节点
  unlink (): void {
    if (this.prev) {
      // 如果有前兄弟节点，说明这不是该层第一个节点，则直接从这一层中删除该节点
      this.prev.next = this.next;
    } else if (this.parent) {
      // 如果是该层中的第一个节点，需要改变父节点的第一个子节点指向
      this.parent.firstChild = this.next;
    }

    if (this.next) {
      // 如果有前兄弟节点，说明这不是该层最后一个节点，则直接从这一层中删除该节点
      this.next.prev = this.prev;
    } else if (this.parent) {
      // 如果是该层中的最后一个节点，需要改变父节点的最后一个子节点指向
      this.parent.lastChild = this.prev;
    }

    // 与父节点及兄弟节点断开连接
    this.parent = null
    this.next = null
    this.prev = null
  }

  // 对该节点添加子节点mnode，插入该节点的子节点层末尾
  appendChild (mnode: MNode): void {
    mnode.unlink();
    mnode.parent = this;
    if (this.lastChild) {
      // 如果该节点已有子节点，则插入子节点层末尾
      this.lastChild.next = mnode;
      mnode.prev = this.lastChild;
      this.lastChild = mnode;
    } else {
      // 如果该节点没有子节点，则为该节点第一个子节点
      this.firstChild = this.lastChild = mnode;
    }
  }

  // 在该节点后插入兄弟节点 mnode
  insertAfter (mnode: MNode): void {
    mnode.unlink();
    // 连接 mnode 与该节点原右兄弟节点
    mnode.next = this.next;
    if (mnode.next) {
      mnode.next.prev = mnode;
    }
    // 连接该节点与 mnode
    mnode.prev = this;
    this.next = mnode;
    // 连接父节点与 mnode
    mnode.parent = this.parent;
    if(!mnode.next && mnode.parent) {
      mnode.parent.lastChild = mnode;
    }
  }
}